<template>
	<view>
		<u-upload ref="uUpload" 
			:auto-upload="true" 
			:action="options.action" 
			:header="options.headers" 
			@on-remove="onRemove" 
			@on-success="onSuccess" 
			@on-choose-complete="onChooseComplete" 
			@on-error="error" 
			:name="options.name"
			:maxCount="maxCount"
			:file-list="fileList" 
			:before-upload="beforeUpload" 
			:is-show-loading="showLoadingUpload" 
			:disabled="disabled"
			:deletable="deletable">
		</u-upload>
		<helang-compress ref="helangCompress"></helang-compress>
	</view>
</template>

<script>
    import {Base64} from '@/common/base64.js'
	import helangCompress from '@/components/helang-compress/helang-compress.vue';
	export default {
		name: 'MyImageUpoad',
		components: {
			helangCompress
		},
		props: {
			maxCount: {
				type: Number,
				default: 50
			},
			fileList: {
				type: Array,
				default() {
					return [];
				}
			},
			disabled: {
				type: Boolean,
				default: false
			},
			deletableProp: {
				type: Boolean,
				default: true
			},
			actionProp: {
				type: String,
				default: ''
			},
			// 是否显示 上传 loading 提示框
			showLoadingUploadProp: {
				type: Boolean,
				default: false
			},
			// 图片上传前是否进行压缩处理
			compressedProp: {
				type: Boolean,
				default: false 
			},
			// 压缩文件的最大大小，单位B(byte)，默认为1M 1024*1024
			compressedFileMaxSizeProp: {
				type: Number,
				default: 1024*1024 
			},
			// 是否显示 压缩处理 loading 提示框
			showLoadingCompressProp: {
				type: Boolean,
				default: false
			},
			// 是否开启物理删除
			enablePhysicalRemoveProp: {
				type: Boolean,
				default: false
			},
			// 物理删除请求的url地址
			physicalRemoveApiUrlProp: {
				type: String,
				default: ''
			},
		},
		data() {
			return {
				options: {
					value: {},
					action: '/api/blade-resource/oss/endpoint/put-file',
					headers: {},
					name: 'file'
				},
				deletable: this.deletableProp,
				showLoadingUpload: this.showLoadingUploadProp,
				showLoadingCompress: this.showLoadingCompressProp,
				// 是否要进行压缩
				compressed: this.compressedProp,
				compressedFileMaxSize: this.compressedFileMaxSizeProp,
				compressParams: {
					maxSize: 800,
					fileType: 'png',
					quality: 0.85,
					minSize: 640
				},
				enablePhysicalRemove: this.enablePhysicalRemoveProp,
				physicalRemoveApiUrl: this.physicalRemoveApiUrlProp
			}
		},
		created(){
			this.getHeader();
			if(this.actionProp) {
				this.options.action = this.actionProp;
			}
		},
		onLoad(){
			
		},
		methods: {
			async beforeUpload(index, list) {
				if(!this.compressed) {
					return true;
				}else {
					let url = list[index].url;
					let originalFileName = 'filename.jpg';
					if(list[index].file && list[index].file.name) {
						originalFileName = list[index].file.name;
					}
					// console.log("开始进行图片压缩处理：index",index,"list",list);
					if(!this.showLoadingCompress && !this.showLoadingUpload) {
						// 如果showLoadingCompress与showLoadingUpload都不开启时，则统一下面提示处理
						uni.showLoading({
							title: "上传中...",
							mask: true
						});
					}
					let compressedTempFilePath = await this.doCompress(url);
					// #ifdef H5
					// 在H5平台下，tempFilePath 为 base64
					let file = this.base64toFile(compressedTempFilePath, originalFileName);
					list[index].file = file;
					let objectURL = window.URL.createObjectURL(file);
					list[index].url = objectURL;
					// #endif
					// #ifndef H5
					// 不是H5平台
					list[index].url = compressedTempFilePath;
					// #endif
					// console.log("图片压缩处理调整后的list",list);
					return true;
				}
			},
			/**
			 * 处理图片压缩
			 * 
			 * @param {Object} filePath
			 */
			async doCompress(filePath) {
				let originSize;
				//判断本地文件的大小
				await uni.getFileInfo({
				    filePath: filePath,
				    success:({size})=>{
						originSize = size;
				        // console.log(size,"压缩前的文件大小",size/1024/1024 + 'M');
				    }
				});
				if(this.showLoadingCompress) {
					uni.showLoading({
						title: '压缩中...',
						mask: true
					});
				}
				let compressedTempFilePath = await this.compressImage.call(this, filePath);
				return compressedTempFilePath;
			},
			onChooseComplete(lists,index) {
				// console.log("lists:",lists,"index:",index);
			},
			onSuccess(data, index, lists){
				// console.log("my-image-upload data",data);
				if(data && typeof data.success === 'boolean' && !data.success) {
					this.$refs.uUpload.uploadError(index, data);
				}
			},
			onRemove(data, removedList){
				this.fileList.splice(data,1);
				// console.log("data",data,"removedList",removedList);
				if(this.enablePhysicalRemove && this.physicalRemoveApiUrl) {
					if(!removedList || (Array.isArray(removedList) && removedList.length == 0)) {
						return;
					}
					let removedFile = removedList[0];
					let removedFileName = '';
					if(removedFile.response && removedFile.response.data) {
						if(removedFile.response.data.name) {
							removedFileName = removedFile.response.data.name;
						}else if(removedFile.response.data.link) {
							removedFileName = removedFile.response.data.link;
						}
					}else {
						removedFileName = removedFile.url; 
					}
					if(!removedFileName) {
						return;
					}
					// 处理物理删除
					let params = {
						fileName: removedFileName
					};
					let url = this.vuex_config.adminPath + this.physicalRemoveApiUrl;
					this.$u.get(url, params).then((res) => {
						// console.log("res",res);
					});
				}
			},
			error(res, index, lists) {
				console.log('onError', res, index, lists);
			},
			getHeader(){
				this.options.headers['Blade-Auth']='bearer ' +`${this.vuex_accessToken}`
				this.options.headers['Authorization'] = `Basic ${Base64.encode(`${this.vuex_config.clientId}:${this.vuex_config.clientSecret}`)}`
			},
			getFileList(){
				let list=[];
				this.$refs.uUpload.lists.forEach((item) => {
					if(item.progress == 100) {
						let json={};
						if(item.response!=undefined){
							json['label']=item.response.data.originalName;
							json['value']= item.response.data.link;
						}else{
							json['label']=item.fileName || item.name
							json['value']= item.url
						}
						list.push(json);
					}
				})
				return list;
			},
			/**
			 * 将base64转为file(h5环境使用)
			 * 
			 * @param {Object} base64
			 * @param {Object} filename
			 */
			base64toFile(base64, filename) {
				if(typeof base64 != 'string') {
					return;
				}
				const arr = base64.split(',');
				if(!arr || arr.length != 2) {
					return;
				}
				const mime = arr[0].match(/:(.*?);/)[1];
				const bstr = atob(arr[1]);
				let n = bstr.length;
				const u8arr = new Uint8Array(n);
				while (n--) {
					u8arr[n] = bstr.charCodeAt(n);
				}
				return new File([u8arr], filename, {
					type: mime
				});
			},
			//图片压缩处理
			async compressImage(imageUrl) {
				let compressedUrl = imageUrl;
				// 定义一个计数器，用于记录循环次数
				let count = 0; 
				// 最终压缩结果是否达到期望
				let compressTargetResult = false;
				while (count < 5) { // 最多循环5次
					count++; // 对计数器加1
					await new Promise((resolve, reject) => {
						this.$refs.helangCompress.compress({
							src: compressedUrl,
							...this.compressParams
						}).then((res) => {
							// console.log("经过helangCompress的compress处理后返回的res",res);
							if(!res) {
								throw new Error("返回的res为空，压缩失败！");
							}
							uni.getFileInfo({
								filePath: res,
								success: ({
									size
								}) => {
									// 1M 相当于 1024 * 1024 字节
									// console.log(size, '压缩后的文件大小',size/1024/1024 + 'M');
									if (size <= this.compressedFileMaxSize) { 
										// 小于指定的compressedFileMaxSize值，则压缩成功
										// console.log('压缩成功');
										if(this.showLoadingCompress) {
											uni.hideLoading();
											uni.showToast({
												title: "压缩成功",
												icon: "none"
											})
										}
										// 更新压缩后的图片路径
										compressedUrl = res;
										compressTargetResult = true;
										resolve();
									} else { 
										// 大于指定的compressedFileMaxSize值，继续压缩
										// 更新压缩后的图片路径
										compressedUrl = res; 
										// console.log('再次压缩，count为：',count);
										compressTargetResult = false;
										resolve();
									}
								}
							})
						}).catch((err) => {
							console.log(err);
							if(this.showLoadingCompress) {
								uni.hideLoading();
								uni.showToast({
									title: "压缩失败",
									icon: "none"
								})
							}
							compressTargetResult = false;
							reject(err);
						}).finally(() => {
							//no handle
						});
					});
					if (compressTargetResult) {
						// console.log("退出循环，已循环次数count为",count);
						// 如果已经成功压缩图片，则退出循环
						break; 
					}
				}
				// console.log("最终压缩的期望结果compressTargetResult",compressTargetResult,"已循环次数count",count);
				if (!compressTargetResult) {
					if(this.showLoadingCompress) {
						uni.hideLoading();
					}else if(!this.showLoadingCompress && !this.showLoadingUpload) {
						uni.hideLoading();
					}
					console.error('经过5次重试仍无法成功压缩图片');
					// throw new Error('经过5次重试仍无法成功压缩图片');
				}
				return compressedUrl;
			}
		}

	}
</script>
